import 'package:cbec_app/utils/AddressDataBase.dart';
import 'package:cbec_app/utils/GlobalData.dart';
import 'package:cbec_app/utils/Tools.dart';
import 'package:cbec_app/utils/logger.dart';

///地址识别
class AddressParse {
  static List defaultData = [];
  static Map mCity = {};
  static Map mArea = {};

  ///处理原始数据
  static List _detailOriginList() {
    List arr = [];
    for (var item in GlobalData.provinceCityAreaList) {
      Map province = {
        'name': _removeKey(item['label']),
        'city': [],
        'isProvince': item['children'][0]['label'] == '市辖区' ? false : true
      };
      arr.add(province);
      //遍历城市
      if (item['children'].length > 0) {
        for (var child in item['children']) {
          Map city = {'name':province['isProvince']? _removeKey(child['label']):_removeKey(item['label']), 'area': []};
          province['city'].add(city);
          //遍历区域
          if (child['children'].length > 0) {
            for (var grand in child['children']) {
              city['area'].add(grand['label']);
            }
          }
        }
      }
      
    }
    return arr;
  }
  ///去除城市或省份关键字
  static _removeKey(String label){
    String str=label;
    var keys=['省','市','自治区','壮族自治区','回族自治区','维吾尔自治区','特别行政区'];
    for(int i=0;i<keys.length;i++){
      if(str.contains(keys[i])){
        str=str.replaceAll(keys[i],'');
      }
    }
    return str;
  }

  static bool _parseArea() {
    if(defaultData.isEmpty){
      defaultData = _detailOriginList();
    }
    
    defaultData.map((province) {
      if (province['city'] != null) {
        province['city'].forEach((city) {
          if (city['name'] != '其他') {
            if (mCity[city['name']] == null) {
              mCity[city['name']] = [];
            }
            mCity[city['name']].add({
              'p': province['name'],
              'c': city['name'],
              'a': city['area'] ?? []
            });
          }
          if (city['area'] != null) {
            city['area'].forEach((area) {
              if (area != '其他') {
                if (mArea[area] == null) {
                  mArea[area] = [];
                }
                mArea[area].add({'p': province['name'], 'c': city['name']});
              }
            });
          }
        });
      }
    });
    return true;
  }

  ///解析地址
  static Map _parseAddress(String address) {
    _parseArea();
    Map parse = {
      'name': '',
      'mobile': '',
      'detail': '',
      'zip_code': '',
      'phone': ''
    };

    //自定义去除关键字，可自行添加
    const List search = [
      '地址',
      '收货地址',
      '收货人',
      '收件人',
      '收货',
      '邮编',
      '电话',
      '：',
      ':',
      '；',
      ';',
      '，',
      ',',
      '。',
      '联系人',
      '\n',
      '手机'
    ];
    for (var str in search) {
      address = address.replaceAll(str, ' ');
    }

    //多个空格replace为一个
    address = address.replaceAll(RegExp('[ ]{2,}'), ' ');
    //整理电话格式
    RegExp phoneReg1 = RegExp('([0-9]{3})-([0-9]{4})-([0-9]{4})');
    Iterable<Match> phones1 = phoneReg1.allMatches(address);
    List<String?> phoneMatches1 = [];
    for (Match m in phones1) {
      phoneMatches1.add(m.group(0));
    }
    if (phoneMatches1.isNotEmpty) {
      phoneMatches1.map((element) {
        address =
            address.replaceFirst(RegExp(element!), element.replaceAll('-', ''));
      });
    }
    RegExp phoneReg2 = RegExp('(\\d{3})[ ](\\d{4})[ ](\\d{4})');
    Iterable<Match> phones2 = phoneReg2.allMatches(address);
    List<String?> phoneMatches2 = [];
    for (Match m in phones2) {
      phoneMatches2.add(m.group(0));
    }
    if (phoneMatches2.isNotEmpty) {
      phoneMatches2.map((element) {
        address =
            address.replaceFirst(RegExp(element!), element.replaceAll(' ', ''));
      });
    }

    RegExp mobileReg =
        RegExp('(86-[1][0-9]{10})|(86[1][0-9]{10})|([1][0-9]{10})');
    Iterable<Match> mobiles = mobileReg.allMatches(address);
    List<String?> mobileMatches = [];
    for (Match m in mobiles) {
      mobileMatches.add(m.group(0));
    }
    if (mobiles.isNotEmpty) {
      parse['phone'] = mobileMatches[0];
      address = address.replaceFirst(mobileMatches[0]!, '');
    }

    //电话/座机
    RegExp phoneReg = RegExp(
        '(([0-9]{3,4}-)[0-9]{7,8})|([0-9]{12})|([0-9]{11})|([0-9]{10})|([0-9]{9})|([0-9]{8})|([0-9]{7})');
    Iterable<Match> phones = phoneReg.allMatches(address);
    List<String?> phoneMatches = [];
    for (Match m in phones) {
      phoneMatches.add(m.group(0));
    }
    if (phones.isNotEmpty) {
      parse['mobile'] = phoneMatches[0];
      address = address.replaceFirst(phoneMatches[0]!, '');
    }
    // //邮编
    // List zipCodeList = _zipCodeFormat();
    // for (int index = 0; index < zipCodeList.length; index++) {
    //   if (address.contains(zipCodeList[index])) {
    //     int num = address.indexOf(zipCodeList[index]);
    //     String code = address.substring(num, num + 6);
    //     parse['zip_code'] = code;
    //     address = address.replaceAll(code, '');
    //   }
    // }

    // address = address.replaceFirst(RegExp('[ ]{2,}'), ' ');

    Map detail = _detailParseForward(address.trim());
    String ignoreArea = detail['province'];
    if (detail['city'] == null || detail['city'] == '') {
      detail = _detailParse(address.trim());
      if ((detail['area'] != null && detail['area'] != '') &&
          (detail['city'] == null || detail['city'] == '')) {
        detail = _detailParse(address.trim(), ignoreArea: true);
      } else {
        //print('smart_parse');
      }
      //这个待完善
      List list = address
          .replaceFirst(detail['province'], '')
          .replaceFirst(detail['city'], '')
          .replaceFirst(detail['area'], '')
          .split(' ');
      list = list.where((str) => (str != null && str != '')).toList();
      //详细住址划分关键字
      //注意：只需要填写关键字最后一位即可：比如单元填写元即可！
      List addressDetailList = ['室', '楼', '元', '号', '幢', '门', '户'];
      if (list.length > 1) {
        list.map((str) {
          if ((parse['name'] == null || parse['name'] == '') ||
              (str != null && str != '') && str.length < parse['name'].length) {
            parse['name'] = str.trim();
          }
        });
        if (parse['name'] != null && parse['name'] != '') {
          detail['addr'] =
              detail['addr'].replaceFirst(parse['name'], '').trim();
        }
      } else {
        //若名字写在详细地址后面，根据address_detail_list进行分割；
        List key = [];
        addressDetailList.map((el) {
          key.add(detail['addr'].indexOf(el));
        });
        key.sort((a, b) {
          return b - a;
        });
        int max = key[0];
        if (detail['name'] != null && detail['name'] != '') {
          parse['name'] = detail['name'];
        }
        if (max != -1) {
          String addrBuild = detail['addr'].substring(0, max + 1);
          String addrNum = detail['addr']
              .replaceFirst(addrBuild, '')
              .replaceAll(new RegExp('[^0-9]+'), '');
          String userName =
              detail['addr'].replaceFirst(addrBuild + addrNum, '');
          detail['addr'] = addrBuild + addrNum;
          parse['name'] = userName;
        }
      }
    } else {
      if (detail['name'] != null && detail['name'] != '') {
        parse['name'] = detail['name'];
      } else {
        List list = detail['addr'].split(' ');
        list = list.where((str) => (str != null && str != '')).toList();
        if (list.length > 1) {
          parse['name'] = list[list.length - 1];
        }
        if (parse['name'] != null && parse['name'] != '') {
          detail['addr'] =
              detail['addr'].replaceFirst(parse['name'], '').trim();
        }
      }
    }
    parse['province'] =
        detail['province'] == '' ? ignoreArea : detail['province'];
    parse['city'] = detail['city'];
    parse['area'] = detail['area'];
    parse['addr'] = detail['addr'];
    parse['result'] = detail['result'];
    //添加省以及市（2019.6.21）输出字段后填入省市等等
    AddressDatabase.foramtProvince.map((el) {
      if (el['name'].indexOf(parse['province']) == 0) {
        parse['province'] = el['name'];
      }
    });
    AddressDatabase.zipCode.map((item) {
      if (parse['province'].indexOf(item['name']) == 0) {
        item['child'].forEach((city) {
          if (city['name'].indexOf(parse['city']) == 0) {
            parse['city'] = city['name'];
          }
        });
      }
    });
    return parse;
  }

  static List _zipCodeFormat() {
    List list = [];
    for (var el in AddressDatabase.zipCode) {
      if (el['child'] != null) {
        el['child'].forEach((event) {
          if (event['child'] != null) {
            event['child'].forEach((element) {
              list.add(element['zipcode']);
            });
          }
        });
      }
    }
    return list;
  }

  static Map _detailParseForward(String address) {
    Map parse = {
      'province': '',
      'city': '',
      'area': '',
      'addr': '',
      'name': '',
    };

    List provinceKey = [
      '特别行政区',
      '古自治区',
      '维吾尔自治区',
      '壮族自治区',
      '回族自治区',
      '自治区',
      '省省直辖',
      '省',
      '市',
    ];
    List cityKey = ['布依族苗族自治州', '苗族侗族自治州', '自治州', '州', '市', '县'];

    for (Map province in defaultData) {
      int index =address.indexOf(province['name']);
      if (index > -1) {
        if (index > 0) {
          //省份不是在第一位，在省份之前的字段识别为名称
          parse['name'] = address.substring(0, index).trim();
          address = address.substring(index);
        }
        if (province['isProvince']) {
          //非直辖市
          parse['province'] = province['name'];
          int length = province['name'].length;
          address = address.substring(length);
        }
        for (String key in provinceKey) {
          if (address.indexOf(key) == 0) {
            address = address.substring(key.length);
          }
        }
        for (Map city in province['city']) {
          index = address.indexOf(city['name']);
          if (index > -1 && index < 3) {
            parse['city'] = city['name'];
            int length1 = parse['city'].length;
            address = address.substring(index + length1);

            for (String key in cityKey) {
              if (address.indexOf(key) == 0) {
                address = address.substring(key.length);
              }
            }
            if (city['area'] != null) {
              for (String area in city['area']) {
                index = address.indexOf(area);
                if (index > -1 && index < 3) {
                  parse['area'] = area;
                  int length2 = parse['area'].length;
                  address = address.substring(index + length2);
                  break;
                }
              }
            }
            break;
          }
        }
        parse['addr'] = address.trim();
        break;
      }
    }
    return parse;
  }

  static Map _detailParse(String address, {bool ignoreArea = false}) {
    Map parse = {
      'province': '',
      'city': '',
      'area': '',
      'name': '',
      '_area': '',
      'addr': '',
    };
    int areaIndex = -1, cityIndex = -1;

    address = address.replaceFirst('  ', ' ');

    if ((!ignoreArea && address.contains('县')) ||
        (!ignoreArea && address.contains('区')) ||
        (!ignoreArea && address.indexOf('旗') > -1)) {
      if (address.contains('旗')) {
        areaIndex = address.indexOf('旗');
        parse['area'] = address.substring(areaIndex - 1, (areaIndex - 1) + 2);
      }
      if (address.contains('区')) {
        areaIndex = address.indexOf('区');
        if (address.lastIndexOf('市', areaIndex) > -1) {
          cityIndex = address.lastIndexOf('市', areaIndex);
          parse['area'] = address.substring(
              cityIndex + 1, (cityIndex + 1) + areaIndex - cityIndex);
        }
      }
      if (address.contains('县')) {
        areaIndex = address.indexOf('县');
        if (address.lastIndexOf('市', areaIndex) > -1) {
          cityIndex = address.lastIndexOf('市', areaIndex);
          parse['area'] = address.substring(
              cityIndex + 1, (cityIndex + 1) + areaIndex - cityIndex);
        } else {
          parse['area'] = address.substring(areaIndex - 2, (areaIndex - 2) + 3);
        }
      }
      parse['addr'] = address.substring(areaIndex + 1);
    } else {
      if (address.contains('市')) {
        areaIndex = address.indexOf('市');
        if (address.split(' ')[0].contains('市')) {
          int areaIndex = address.split(' ')[0].indexOf('市');
          parse['area'] = address.split(' ')[0].substring(0, areaIndex + 1);
          parse['addr'] = address.split(' ')[0].substring(areaIndex + 1);
          if (address.split(' ').length > 1) {
            parse['name'] = address.split(' ')[1];
          } else {
            parse['name'] = '';
          }
        } else {
          if (address.split(' ').length > 1) {
            int areaIndex = address.split(' ')[1].indexOf('市');
            parse['area'] = address.split(' ')[1].substring(0, areaIndex + 1);
            parse['addr'] = address.split(' ')[1].substring(areaIndex + 1);
          } else {
            parse['area'] = '';
            parse['addr'] = '';
          }
          parse['name'] = address.split(' ')[0];
        }
      } else {
        parse['addr'] = address;
      }
    }

    if (address.contains('市') ||
        address.contains('盟') ||
        address.contains('州')) {
      if (address.contains('市')) {
        parse['_area'] =
            address.substring(address.indexOf('市') - 2, address.indexOf('市'));
      }
      if (address.contains('盟') &&
          (mCity[parse['_area']] == null ||
              mCity[parse['_area']].length == 0)) {
        parse['_area'] =
            address.substring(address.indexOf('盟') - 2, address.indexOf('盟'));
      }
      if (address.contains('州') &&
          (mCity[parse['_area']] == null ||
              mCity[parse['_area']].length == 0)) {
        parse['_area'] =
            address.substring(address.indexOf('州') - 2, address.indexOf('州'));
      }
    }

    parse['area'] = parse['area'].trim();
    if (parse['area'] != null &&
        parse['area'] != '' &&
        mArea[parse['area']] != null) {
      if (mArea[parse['area']].length == 1) {
        parse['province'] = mArea[parse['area']][0]['p'];
        parse['city'] = mArea[parse['area']][0]['c'];
      } else {
        parse['_area'] = parse['_area'].trim();
        String addr = address.substring(0, areaIndex);
        Map d = {};
        for (Map item in mArea[parse['area']]) {
          if (item['p'].indexOf(addr) > -1 || item['c'] == parse['_area']) {
            d = item;
            break;
          }
        }
        if (d.isNotEmpty) {
          parse['province'] = d['p'];
          parse['city'] = d['c'];
        } else {
          parse['result'] = mArea[parse['area']];
        }
      }
    } else {
      if (parse['_area'] != null && parse['_area'] != '') {
        List city = mCity[parse['_area']];
        if (city.length > 0) {
          parse['province'] = city[0].p;
          parse['city'] = city[0].c;
          int cityIndex = address.indexOf(parse['city']);
          int length3 = parse['city'].length + 1;
          parse['addr'] = address.substring(cityIndex + length3);
          parse['area'] = '';
          for (String area in city[0]['a']) {
            if (parse['addr'].indexOf(area) == 0) {
              parse['area'] = area;
              parse['addr'] = parse['addr'].replaceFirst(area, '');
              break;
            }
          }
        }
      } else {
        parse['area'] = '';
      }
    }
    parse['addr'] = parse['addr'].trim();
    return parse;
  }

  ///解析出省市区极其编码
  static Map parseAddressToCode(String address) {
    var info = _parseAddress(address);
    logger.d('初步 $info');
    if (info['city'] == '海外') {
      Tools.showToast('暂不支持识别海外地址');
    }
    Map detail = {
      'provinceCode': '',
      'provinceName': info['province'],
      'cityCode': '',
      'cityName': info['city'],
      'areaCode': '',
      'areaName': '',
      'address': info['addr'],
      'name': info['name'],
      'phone': info['phone'] ?? info['mobile']
    };
    for (var item in GlobalData.provinceCityAreaList) {
      //查找省份
      if (info['province'] != '' &&
          item['label'].toString().contains(info['province'])) {
        detail['provinceCode'] = item['value'];
        detail['provinceName'] = item['label'];
        List cityList = item['children'];
        //查找城市
        if (cityList.isNotEmpty) {
          for (var child in cityList) {
            if (child['label'].toString().contains(info['city'])) {
              detail['cityCode'] = child['value'];
              detail['cityName'] = child['label'];
              //查找区
              List areaList = child['children'];
              for (var grandItem in areaList) {
                if (grandItem['label'].toString().contains(info['area'])) {
                  detail['areaCode'] = grandItem['value'];
                  detail['areaName'] = grandItem['label'];
                }
              }
            }
          }
        }
      } else {
        //查找直辖市
        if (item['label'].toString().contains(info['city'])) {
          detail['provinceCode'] = item['value'];
          detail['provinceName'] = item['label'];
          //查找区
          List areaList = [];
          if (item['children'][0]['children'].length > 0) {
            //直辖市
            areaList = item['children'][0]['children'];
          } else {
            //特别行政区和海外
            areaList = item['children'];
          }
          for (var grandItem in areaList) {
            if (grandItem['label'].toString().contains(info['area'])) {
              detail['cityCode'] = grandItem['value'];
              detail['cityName'] = grandItem['label'];
            }
          }
        }
      }
    }
    return detail;
  }
}
